package cn.virens.util.poi;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.virens.util.poi.read.CellReader;
import cn.virens.util.poi.read.RowObject;

/**
 * excel 导入
 * 
 * @author loioi
 */
public class SimpleExcelImport {
	private Logger logger = LoggerFactory.getLogger(SimpleExcelImport.class);
	private int startRow = 0;
	private int endRow = Integer.MAX_VALUE;
	private ReadSheetListener sheetListener;

	private List<CellReader<?>> feilds = new ArrayList<>();

	/**
	 * 开始导入
	 * 
	 * @param filePath 表格文件路径
	 * @param sheetAt 工作簿
	 * @return
	 * @throws Exception
	 */
	public List<RowObject> imported(String filePath, int sheetAt) throws Exception {
		XSSFWorkbook xssfWorkbook = new XSSFWorkbook(new FileInputStream(filePath));// 输出表格
		try {
			return imported(xssfWorkbook.getSheetAt(sheetAt));
		} finally {
			if (xssfWorkbook != null) xssfWorkbook.close();
		}
	}

	/**
	 * 开始导入
	 * 
	 * @param file 表格文件
	 * @param sheetAt 工作簿
	 * @return
	 * @throws Exception
	 */
	public List<RowObject> imported(File file, int sheetAt) throws Exception {
		XSSFWorkbook xssfWorkbook = new XSSFWorkbook(new FileInputStream(file));// 输出表格
		try {
			return imported(xssfWorkbook.getSheetAt(sheetAt));
		} finally {
			if (xssfWorkbook != null) xssfWorkbook.close();
		}
	}

	/**
	 * 开始导入
	 * 
	 * @param inputStream 表格文件流
	 * @param sheetAt 工作簿
	 * @return
	 * @throws Exception
	 */
	public List<RowObject> imported(InputStream inputStream, int sheetAt) throws Exception {
		XSSFWorkbook xssfWorkbook = new XSSFWorkbook(inputStream);// 输出表格
		try {
			return imported(xssfWorkbook.getSheetAt(sheetAt));
		} finally {
			if (xssfWorkbook != null) xssfWorkbook.close();
		}
	}

	/**
	 * 开始导入
	 * 
	 * @param xssfSheet 工作簿
	 * @return
	 * @throws Exception
	 */
	public List<RowObject> imported(XSSFSheet xssfSheet) throws Exception {
		List<RowObject> result = new ArrayList<>();

		int _endRow = Math.min(endRow, xssfSheet.getLastRowNum());
		int _startRow = Math.max(startRow, xssfSheet.getFirstRowNum());

		// 如果有读取工作蒲的监听，则调用，并根据返回值判断是否继续读取
		if (sheetListener != null && !sheetListener.read(xssfSheet)) return null;

		/* 循环读取数据 */
		for (int i = _startRow; i <= _endRow; i++) {
			XSSFRow xssfRow = xssfSheet.getRow(i);// 获取行
			if (xssfRow == null) continue;

			RowObject rowObject = new RowObject(i);
			logger.debug("正在读取{}行...", i);
			/* 读取数据 */
			for (CellReader<?> feild : feilds) {
				rowObject.addCellObject(feild, xssfRow);
			}

			result.add(rowObject);
		}

		return result;
	}

	/**
	 * 获取读取起始行
	 * 
	 * @return
	 */
	public int getStartRow() {
		return startRow;
	}

	/**
	 * 设置读取起始行
	 * 
	 * @param startRow
	 */
	public void setStartRow(int startRow) {
		this.startRow = startRow;
	}

	/**
	 * 获取读取终止行
	 * 
	 * @return
	 */
	public int getEndRow() {
		return endRow;
	}

	/**
	 * 设置读取终止行
	 * 
	 * @param endRow
	 */
	public void setEndRow(int endRow) {
		this.endRow = endRow;
	}

	public ReadSheetListener getSheetListener() {
		return sheetListener;
	}

	public void setSheetListener(ReadSheetListener sheetListener) {
		this.sheetListener = sheetListener;
	}

	public <D> boolean addFeild(CellReader<D> readCell) {
		return this.feilds.add(readCell);
	}

	public <D> boolean addFeild(int index, String name, CellReader.ReadListener<D> listener) {
		CellReader<D> d = new CellReader<D>();
		d.setName(name);
		d.setIndex(index);
		d.setReadListener(listener);

		return this.addFeild(d);
	}

	public interface ReadSheetListener {
		boolean read(Sheet xssfSheet);
	}
}
